home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1994 November: Tool Chest / Dev.CD Nov 94.toast / Tool Chest / Development Tools & Languages / • Other Platforms / PCCTS / support / genmk / genmk.c next >
Encoding:
C/C++ Source or Header  |  1994-09-14  |  14.3 KB  |  620 lines  |  [TEXT/MPS ]

  1. /*
  2.  * genmk -- a program to make makefiles for PCCTS
  3.  *
  4.  * ANTLR 1.21
  5.  * Terence John Parr 1989 - 1994
  6.  * Purdue University
  7.  * U of MN
  8.  */
  9. #include <stdio.h>
  10. #include "config.h" /* be sensitive to what ANTLR/DLG call the files */
  11.  
  12. #ifdef VAXC
  13. #define DIE        return 0;
  14. #define DONE    return 1;
  15. #else
  16. #define DIE        return 1;
  17. #define DONE    return 0;
  18. #endif
  19.  
  20. #ifndef require
  21. #define require(expr, err) {if ( !(expr) ) fatal(err);}
  22. #endif
  23.  
  24. #define MAX_FILES    50
  25. #define MAX_CLASSES    50
  26.  
  27. char *dlg = "parser.dlg";
  28. char *err = "err.c";
  29. char *hdr = "stdpccts.h";
  30. char *tok = "tokens.h";
  31. char *mode = "mode.h";
  32. char *scan = "scan";
  33.  
  34. char ATOKENBUFFER_O[100];
  35. char APARSER_O[100];
  36. char ASTBASE_O[100];
  37. char DLEXERBASE_O[100];
  38.  
  39. /* Option flags */
  40. static char *project="t", *files[MAX_FILES], *classes[MAX_CLASSES];
  41. static int    num_files = 0;
  42. static int    num_classes = 0;
  43. static int    user_lexer = 0;
  44. static char    *user_token_types = NULL;
  45. static int    gen_CPP = 0;
  46. static char *outdir=".";
  47. static char *dlg_class = "DLGLexer";
  48. static int    gen_trees = 0;
  49.  
  50. typedef struct _Opt {
  51.             char *option;
  52.             int  arg;
  53. #ifdef __cplusplus
  54.             void (*process)(...);
  55. #else
  56.             void (*process)();
  57. #endif
  58.             char *descr;
  59.         } Opt;
  60.  
  61. #ifdef __STDC__
  62. static void ProcessArgs(int, char **, Opt *);
  63. #else
  64. static void ProcessArgs();
  65. #endif
  66.  
  67. static void
  68. pProj( s, t )
  69. char *s;
  70. char *t;
  71. {
  72.     project = t;
  73. }
  74.  
  75. static void
  76. pUL( s )
  77. char *s;
  78. {
  79.     user_lexer = 1;
  80. }
  81.  
  82. static void
  83. pCPP( s )
  84. char *s;
  85. {
  86.     gen_CPP = 1;
  87. }
  88.  
  89. static void
  90. pUT( s, t )
  91. char *s;
  92. char *t;
  93. {
  94.     user_token_types = t;
  95. }
  96.  
  97. static void
  98. pTrees( s )
  99. char *s;
  100. {
  101.     gen_trees = 1;
  102. }
  103.  
  104. static void
  105. #ifdef __STDC__
  106. pFile( char *s )
  107. #else
  108. pFile( s )
  109. char *s;
  110. #endif
  111. {
  112.     if ( *s=='-' )
  113.     {
  114.         fprintf(stderr, "invalid option: '%s'; ignored...",s);
  115.         return;
  116.     }
  117.  
  118.     require(num_files<MAX_FILES, "exceeded max # of input files");
  119.     files[num_files++] = s;
  120. }
  121.  
  122. static void
  123. #ifdef __STDC__
  124. pClass( char *s, char *t )
  125. #else
  126. pClass( s, t )
  127. char *s;
  128. char *t;
  129. #endif
  130. {
  131.     require(num_classes<MAX_CLASSES, "exceeded max # of grammar classes");
  132.     classes[num_classes++] = t;
  133. }
  134.  
  135. static void
  136. #ifdef __STDC__
  137. pDLGClass( char *s, char *t )
  138. #else
  139. pDLGClass( s, t )
  140. char *s;
  141. char *t;
  142. #endif
  143. {
  144.     if ( !gen_CPP ) {
  145.         fprintf(stderr, "-dlg-class makes no sense without C++ mode; ignored...");
  146.     }
  147.     else dlg_class = t;
  148. }
  149.  
  150. static void
  151. #ifdef __STDC__
  152. pOdir( char *s, char *t )
  153. #else
  154. pOdir( s, t )
  155. char *s;
  156. char *t;
  157. #endif
  158. {
  159.     outdir = t;
  160. }
  161.  
  162. static void
  163. #ifdef __STDC__
  164. pHdr( char *s, char *t )
  165. #else
  166. pHdr( s, t )
  167. char *s;
  168. char *t;
  169. #endif
  170. {
  171.     hdr = t;
  172. }
  173.  
  174. Opt options[] = {
  175.     { "-CC", 0,    pCPP,            "Generate C++ output"},
  176.     { "-class", 1,    pClass,        "Name of a grammar class defined in grammar (if C++)"},
  177.     { "-dlg-class", 1,pDLGClass,"Name of DLG lexer class (default=DLGLexer) (if C++)"},
  178.     { "-header", 1,pHdr,        "Name of ANTLR standard header info (default=no file)"},
  179.     { "-o", 1,    pOdir,            "Directory where output files should go (default=\".\")"},
  180.     { "-project", 1,    pProj,    "Name of executable to create (default=t)"},
  181.     { "-token-types", 1, pUT,    "Token types are in this file (don't use tokens.h)"},
  182.     { "-trees", 0, pTrees,        "Generate ASTs"},
  183.     { "-user-lexer", 0,    pUL,    "Do not create a DLG-based scanner"},
  184.     { "*",  0,            pFile,     "" },    /* anything else is a file */
  185.     { NULL, 0, NULL, NULL }
  186. };
  187.  
  188. extern char *DIR();
  189.  
  190. main(argc, argv)
  191. int argc;
  192. char **argv;
  193. {
  194.     if ( argc == 1 ) { help(); DIE; }
  195.     ProcessArgs(argc-1, &(argv[1]), options);
  196.  
  197.     strcpy(ATOKENBUFFER_O, ATOKENBUFFER_C);
  198.     ATOKENBUFFER_O[strlen(ATOKENBUFFER_C)-1] = '\0';
  199.     strcat(ATOKENBUFFER_O, "$(OBJEXT)");
  200.     strcpy(APARSER_O, APARSER_C);
  201.     APARSER_O[strlen(APARSER_C)-1] = '\0';
  202.     strcat(APARSER_O, "$(OBJEXT)");
  203.     strcpy(ASTBASE_O, ASTBASE_C);
  204.     ASTBASE_O[strlen(ASTBASE_C)-1] = '\0';
  205.     strcat(ASTBASE_O, "$(OBJEXT)");
  206.     strcpy(DLEXERBASE_O, DLEXERBASE_C);
  207.     DLEXERBASE_O[strlen(DLEXERBASE_C)-1] = '\0';
  208.     strcat(DLEXERBASE_O, "$(OBJEXT)");
  209.  
  210.     if ( num_files == 0 ) fatal("no grammar files specified; exiting...");
  211.     if ( !gen_CPP && num_classes>0 ) {
  212.         warn("can't define classes w/o C++ mode; turning on C++ mode...\n");
  213.         gen_CPP=1;
  214.     }
  215.     if ( gen_CPP && num_classes==0 ) {
  216.         fatal("must define classes >0 grammar classes in C++ mode\n");
  217.     }
  218.  
  219.     mk(project, files, num_files, argc, argv);
  220.     DONE;
  221. }
  222.  
  223. help()
  224. {
  225.     Opt *p = options;
  226.     static char buf[1000+1];
  227.  
  228.     fprintf(stderr, "genmk [options] f1.g ... fn.g\n");
  229.     while ( p->option!=NULL && *(p->option) != '*' )
  230.     {
  231.         buf[0]='\0';
  232.         if ( p->arg ) sprintf(buf, "%s ___", p->option);
  233.         else strcpy(buf, p->option);
  234.         fprintf(stderr, "\t%-16s   %s\n", buf, p->descr);
  235.         p++;
  236.     }
  237. }
  238.  
  239. mk(project, files, n, argc, argv)
  240. char *project;
  241. char **files;
  242. int n;
  243. int argc;
  244. char **argv;
  245. {
  246.     int i;
  247.  
  248.     printf("#\n");
  249.     printf("# PCCTS makefile for: ");
  250.     pfiles(files, n, NULL);
  251.     printf("\n");
  252.     printf("#\n");
  253.     printf("# Created from:");
  254.     for (i=0; i<argc; i++) printf(" %s", argv[i]);
  255.     printf("\n");
  256.     printf("#\n");
  257.     printf("# PCCTS release 1.21\n");
  258.     printf("# Project: %s\n", project);
  259.     if ( gen_CPP ) printf("# C++ output\n");
  260.     else printf("# C output\n");
  261.     if ( user_lexer ) printf("# User-defined scanner\n");
  262.     else printf("# DLG scanner\n");
  263.     if ( user_token_types!=NULL ) printf("# User-defined token types in '%s'\n", user_token_types);
  264.     else printf("# ANTLR-defined token types\n");
  265.     printf("#\n");
  266.     if ( user_token_types!=NULL ) {
  267.         printf("# Make sure #tokdefs directive in ANTLR grammar lists this file:\n");
  268.         printf("TOKENS = %s", user_token_types);
  269.     }
  270.     else printf("TOKENS = %stokens.h", DIR());
  271.     printf("\n");
  272.     printf("#\n");
  273.     printf("# The following filenames must be consistent with ANTLR/DLG flags\n");
  274.     printf("DLG_FILE = %s%s\n", DIR(), dlg);
  275.     printf("ERR = %serr\n", DIR());
  276.     if ( strcmp(hdr,"stdpccts.h")!=0 ) printf("HDR_FILE = %s%s\n", DIR(), hdr);
  277.     else printf("HDR_FILE =\n");
  278.     if ( !gen_CPP ) printf("MOD_FILE = %s%s\n", DIR(), mode);
  279.     if ( !gen_CPP ) printf("SCAN = %s\n", scan);
  280.     else printf("SCAN = %s%s\n", DIR(), dlg_class);
  281.  
  282.     printf("OBJEXT = %s\n", OBJ_FILE_SUFFIX+1);
  283.     printf("PCCTS = .\n");
  284.     printf("ANTLR_H = $(PCCTS)%sh\n", DirectorySymbol);
  285.     printf("BIN = $(PCCTS)%sbin\n", DirectorySymbol);
  286.     printf("ANTLR = $(BIN)%santlr\n", DirectorySymbol);
  287.     printf("DLG = $(BIN)%sdlg\n", DirectorySymbol);
  288.     printf("CFLAGS = -I. -I$(ANTLR_H)");
  289.     if ( strcmp(outdir, ".")!=0 ) printf(" -I%s", outdir);
  290.     printf("\n");
  291.     printf("AFLAGS =");
  292.     if ( strcmp(outdir,".")!=0 ) printf(" -o %s", outdir);
  293.     if ( user_lexer ) printf(" -gx");
  294.     if ( gen_CPP ) printf(" -CC");
  295.     if ( strcmp(hdr,"stdpccts.h")!=0 ) printf(" -gh %s", hdr);
  296.     if ( gen_trees ) printf(" -gt");
  297.     printf("\n");
  298.     printf("DFLAGS = -C2 -i");
  299.     if ( gen_CPP ) printf(" -CC");
  300.     if ( strcmp(dlg_class,"DLGLexer")!=0 ) printf(" -cl %s", dlg_class);
  301.     if ( strcmp(outdir,".")!=0 ) printf(" -o %s", outdir);
  302.     printf("\n");
  303.     printf("GRM = ");
  304.     pfiles(files, n, NULL);
  305.     printf("\n");
  306.     printf("SRC = ");
  307.     if ( gen_CPP ) pfiles(files, n, "C");
  308.     else pfiles(files, n, "c");
  309.     if ( gen_CPP ) {
  310.         printf(" \\\n     ");
  311.         printf(" ");
  312.         pclasses(classes, num_classes, "C");
  313.         printf(" \\\n      ");
  314.         printf("$(ANTLR_H)%s%s", DirectorySymbol, APARSER_C);
  315.         if ( !user_lexer ) printf(" $(ANTLR_H)%s%s", DirectorySymbol, DLEXERBASE_C);
  316.         if ( gen_trees ) printf(" $(ANTLR_H)%s%s", DirectorySymbol, ASTBASE_C);
  317.         printf(" $(ANTLR_H)%s%s", DirectorySymbol, ATOKENBUFFER_C);
  318.     }
  319.     if ( !user_lexer ) {
  320.         if ( gen_CPP ) printf(" $(SCAN)%s", CPP_FILE_SUFFIX);
  321.         else printf(" %s$(SCAN).c", DIR());
  322.     }
  323.     if ( !gen_CPP ) printf(" $(ERR).c");
  324.     printf("\n");
  325.     printf("OBJ = ");
  326.     pfiles(files, n, "o");
  327.     if ( gen_CPP ) {
  328.         printf(" \\\n     ");
  329.         printf(" ");
  330.         pclasses(classes, num_classes, "o");
  331.         printf(" \\\n      ");
  332.         printf(" %s%s", DIR(), APARSER_O);
  333.         if ( !user_lexer ) {
  334.             printf(" %s%s", DIR(), DLEXERBASE_O);
  335.         }
  336.         if ( gen_trees ) printf(" %s%s", DIR(), ASTBASE_O);
  337.         printf(" %s%s", DIR(), ATOKENBUFFER_O);
  338.     }
  339.     if ( !user_lexer ) {
  340.         if ( gen_CPP ) printf(" $(SCAN).$(OBJEXT)");
  341.         else printf(" %s$(SCAN).$(OBJEXT)", DIR());
  342.     }
  343.     if ( !gen_CPP ) printf(" $(ERR).$(OBJEXT)");
  344.     printf("\n");
  345.  
  346.     printf("ANTLR_SPAWN = ");
  347.     if ( gen_CPP ) pfiles(files, n, "C");
  348.     else pfiles(files, n, "c");
  349.     if ( gen_CPP ) {
  350.         printf(" ");
  351.         pclasses(classes, num_classes, "C");
  352.         printf(" \\\n              ");
  353.         pclasses(classes, num_classes, "h");
  354.         if ( strcmp(hdr,"stdpccts.h")!=0 ) {
  355.             printf(" \\\n              ");
  356.             printf("$(HDR_FILE) stdpccts.h");
  357.         }
  358.     }
  359.     if ( user_lexer ) {
  360.         if ( !user_token_types ) printf(" $(TOKENS)");
  361.     }
  362.     else {
  363.         printf(" $(DLG_FILE)");
  364.         if ( !user_token_types ) printf(" $(TOKENS)");
  365.     }
  366.     if ( !gen_CPP ) printf(" $(ERR).c");
  367.     printf("\n");
  368.  
  369.     if ( !user_lexer ) {
  370.         if ( gen_CPP ) printf("DLG_SPAWN = $(SCAN)%s", CPP_FILE_SUFFIX);
  371.         else printf("DLG_SPAWN = %s$(SCAN).c", DIR());
  372.         if ( gen_CPP ) printf(" $(SCAN).h");
  373.         if ( !gen_CPP ) printf(" $(MOD_FILE)");
  374.         printf("\n");
  375.     }
  376.  
  377.     if ( gen_CPP ) {
  378.         printf("#CCC=g++\n");
  379.         printf("CC=$(CCC)\n");
  380.     }
  381.     else printf("#CC=cc\n");
  382.  
  383.     /* set up dependencies */
  384.     printf("\n%s : $(OBJ) $(SRC)\n", project);
  385.     printf("    %s -o %s $(CFLAGS) $(OBJ)\n", gen_CPP?"$(CCC)":"$(CC)",project);
  386.     printf("\n");
  387.  
  388.     /* how to compile parser files */
  389.  
  390.     for (i=0; i<num_files; i++)
  391.     {
  392.         pfiles(&files[i], 1, "o");
  393.         if ( user_lexer ) {
  394.             printf(" : $(TOKENS)");
  395.         }
  396.         else {
  397.             if ( gen_CPP ) printf(" : $(TOKENS) $(SCAN).h");
  398.             else printf(" : $(MOD_FILE) $(TOKENS)");
  399.         }
  400.         printf(" ");
  401.         if ( gen_CPP ) pfiles(&files[i], 1, "C");
  402.         else pfiles(&files[i], 1, "c");
  403.         if ( gen_CPP && strcmp(hdr,"stdpccts.h")!=0 ) printf(" $(HDR_FILE)");
  404.         printf("\n");
  405.         printf("    %s -c $(CFLAGS) -o ",gen_CPP?"$(CCC)":"$(CC)");
  406.         pfiles(&files[i], 1, "o");
  407.         printf(" ");
  408.         if ( gen_CPP ) pfiles(&files[i], 1, "C");
  409.         else pfiles(&files[i], 1, "c");
  410.         printf("\n\n");
  411.     }
  412.  
  413.     /* how to compile err.c */
  414.     if ( !gen_CPP ) {
  415.         printf("$(ERR).$(OBJEXT) : $(ERR).c");
  416.         if ( !user_lexer ) printf(" $(TOKENS)");
  417.         printf("\n");
  418.         printf("    %s -c $(CFLAGS) -o $(ERR).$(OBJEXT) $(ERR).c",gen_CPP?"$(CCC)":"$(CC)");
  419.         printf("\n\n");
  420.     }
  421.  
  422.     /* how to compile Class.c */
  423.     for (i=0; i<num_classes; i++)
  424.     {
  425.         pclasses(&classes[i], 1, "o");
  426.         if ( user_lexer ) {
  427.             printf(" : $(TOKENS)");
  428.         }
  429.         else {
  430.             printf(" : $(TOKENS) $(SCAN).h");
  431.         }
  432.         printf(" ");
  433.         pclasses(&classes[i], 1, "C");
  434.         printf(" ");
  435.         pclasses(&classes[i], 1, "h");
  436.         if ( gen_CPP && strcmp(hdr,"stdpccts.h")!=0 ) printf(" $(HDR_FILE)");
  437.         printf("\n");
  438.         printf("    %s -c $(CFLAGS) -o ",gen_CPP?"$(CCC)":"$(CC)");
  439.         pclasses(&classes[i], 1, "o");
  440.         printf(" ");
  441.         pclasses(&classes[i], 1, "C");
  442.         printf("\n\n");
  443.     }
  444.  
  445.     /* how to compile scan.c */
  446.     if ( !user_lexer ) {
  447.         if ( gen_CPP ) printf("$(SCAN).$(OBJEXT) : $(SCAN)%s", CPP_FILE_SUFFIX);
  448.         else printf("%s$(SCAN).$(OBJEXT) : %s$(SCAN).c", DIR(), DIR());
  449.         if ( !user_lexer ) printf(" $(TOKENS)");
  450.         printf("\n");
  451.         if ( gen_CPP ) printf("    $(CCC) -c $(CFLAGS) -o $(SCAN).$(OBJEXT) $(SCAN)%s", CPP_FILE_SUFFIX);
  452.         else printf("    $(CC) -c $(CFLAGS) -o %s$(SCAN).$(OBJEXT) %s$(SCAN).c", DIR(), DIR());
  453.         printf("\n\n");
  454.     }
  455.  
  456.     printf("$(ANTLR_SPAWN) : $(GRM)\n");
  457.     printf("    $(ANTLR) $(AFLAGS) $(GRM)\n");
  458.  
  459.     if ( !user_lexer )
  460.     {
  461.         printf("\n");
  462.         printf("$(DLG_SPAWN) : $(DLG_FILE)\n");
  463.         if ( gen_CPP ) printf("    $(DLG) $(DFLAGS) $(DLG_FILE)\n");
  464.         else printf("    $(DLG) $(DFLAGS) $(DLG_FILE) $(SCAN).c\n");
  465.     }
  466.  
  467.     /* do the makes for ANTLR/DLG support */
  468.     if ( gen_CPP ) {
  469.         printf("\n");
  470.         printf("%s%s : $(ANTLR_H)%s%s\n", DIR(), APARSER_O, DirectorySymbol, APARSER_C);
  471.         printf("    %s -c $(CFLAGS) -o ",gen_CPP?"$(CCC)":"$(CC)");
  472.         printf("%s%s $(ANTLR_H)%s%s\n", DIR(), APARSER_O, DirectorySymbol, APARSER_C);
  473.         printf("\n");
  474.         printf("%s%s : $(ANTLR_H)%s%s\n", DIR(), ATOKENBUFFER_O, DirectorySymbol, ATOKENBUFFER_C);
  475.         printf("    %s -c $(CFLAGS) -o ",gen_CPP?"$(CCC)":"$(CC)");
  476.         printf("%s%s $(ANTLR_H)%s%s\n", DIR(), ATOKENBUFFER_O, DirectorySymbol, ATOKENBUFFER_C);
  477.         if ( !user_lexer ) {
  478.             printf("\n");
  479.             printf("%s%s : $(ANTLR_H)%s%s\n", DIR(), DLEXERBASE_O, DirectorySymbol, DLEXERBASE_C);
  480.             printf("    %s -c $(CFLAGS) -o ",gen_CPP?"$(CCC)":"$(CC)");
  481.             printf("%s%s $(ANTLR_H)%s%s\n", DIR(), DLEXERBASE_O, DirectorySymbol, DLEXERBASE_C);
  482.         }
  483.         if ( gen_trees ) {
  484.             printf("\n");
  485.             printf("%s%s : $(ANTLR_H)%s%s\n", DIR(), ASTBASE_O, DirectorySymbol, ASTBASE_C);
  486.             printf("    %s -c $(CFLAGS) -o ",gen_CPP?"$(CCC)":"$(CC)");
  487.             printf("%s%s $(ANTLR_H)%s%s\n", DIR(), ASTBASE_O, DirectorySymbol, ASTBASE_C);
  488.         }
  489.     }
  490.  
  491.     /* clean and scrub targets */
  492.  
  493.     printf("\nclean:\n");
  494.     printf("    rm -f *.$(OBJEXT) core %s", project);
  495.     if ( strcmp(outdir, ".")!=0 ) printf(" %s*.$(OBJEXT)", DIR());
  496.     printf("\n");
  497.  
  498.     printf("\nscrub:\n");
  499.     printf("    rm -f *.$(OBJEXT) core %s", project);
  500.     if ( strcmp(outdir, ".")!=0 ) printf(" %s*.$(OBJEXT)", DIR());
  501.     printf(" $(ANTLR_SPAWN)");
  502.     if ( !user_lexer ) printf(" $(DLG_SPAWN)");
  503.     printf("\n");
  504. }
  505.  
  506. pfiles(files, n, suffix)
  507. char **files;
  508. int n;
  509. char *suffix;
  510. {
  511.     int first=1;
  512.  
  513.     while ( n>0 )
  514.     {
  515.         char *p = &(*files)[strlen(*files)-1];
  516.         if ( !first ) putchar(' ');
  517.         first=0;
  518.         while ( p > *files && *p != '.' ) --p;
  519.         if ( p == *files )
  520.         {
  521.             fprintf(stderr,
  522.                     "genmk: filenames must be file.suffix format: %s\n",
  523.                     *files);
  524.             exit(-1);
  525.         }
  526.         if ( suffix == NULL ) printf("%s", *files);
  527.         else
  528.         {
  529.             *p = '\0';
  530.             printf("%s", DIR());
  531.             if ( strcmp(suffix, "o")==0 ) printf("%s.$(OBJEXT)", *files);
  532.             else printf("%s.%s", *files, suffix);
  533.             *p = '.';
  534.         }
  535.         files++;
  536.         --n;
  537.     }
  538. }
  539.  
  540. pclasses(classes, n, suffix)
  541. char **classes;
  542. int n;
  543. char *suffix;
  544. {
  545.     int first=1;
  546.  
  547.     while ( n>0 )
  548.     {
  549.         if ( !first ) putchar(' ');
  550.         first=0;
  551.         if ( suffix == NULL ) printf("%s", *classes);
  552.         else {
  553.             printf("%s", DIR());
  554.             if ( strcmp(suffix, "o")==0 ) printf("%s.$(OBJEXT)", *classes);
  555.             else printf("%s.%s", *classes, suffix);
  556.         }
  557.         classes++;
  558.         --n;
  559.     }
  560. }
  561.  
  562. static void
  563. #ifdef __STDC__
  564. ProcessArgs( int argc, char **argv, Opt *options )
  565. #else
  566. ProcessArgs( argc, argv, options )
  567. int argc;
  568. char **argv;
  569. Opt *options;
  570. #endif
  571. {
  572.     Opt *p;
  573.     require(argv!=NULL, "ProcessArgs: command line NULL");
  574.  
  575.     while ( argc-- > 0 )
  576.     {
  577.         p = options;
  578.         while ( p->option != NULL )
  579.         {
  580.             if ( strcmp(p->option, "*") == 0 ||
  581.                  strcmp(p->option, *argv) == 0 )
  582.             {
  583.                 if ( p->arg )
  584.                 {
  585.                     (*p->process)( *argv, *(argv+1) );
  586.                     argv++;
  587.                     argc--;
  588.                 }
  589.                 else
  590.                     (*p->process)( *argv );
  591.                 break;
  592.             }
  593.             p++;
  594.         }
  595.         argv++;
  596.     }
  597. }
  598.  
  599. fatal( err_)
  600. char *err_;
  601. {
  602.     fprintf(stderr, "genmk: %s\n", err_);
  603.     exit(1);
  604. }
  605.  
  606. warn( err_)
  607. char *err_;
  608. {
  609.     fprintf(stderr, "genmk: %s\n", err_);
  610. }
  611.  
  612. char *DIR()
  613. {
  614.     static char buf[200+1];
  615.     
  616.     if ( strcmp(outdir,TopDirectory)==0 ) return "";
  617.     sprintf(buf, "%s%s", outdir, DirectorySymbol);
  618.     return buf;
  619. }
  620.